package 图;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class 课程表 {
    List<ArrayList<Integer>> edges;
    int[] visited;
    boolean valid = true;


    //bfs
    public static boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] indegrees = new int[numCourses];
        List<ArrayList<Integer>> adjacencyies = new ArrayList<>();
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            adjacencyies.add(new ArrayList<Integer>());
        }
        for (int[] prerequisite : prerequisites) {
            indegrees[prerequisite[0]]++;
            adjacencyies.get(prerequisite[1]).add(prerequisite[0]);
        }
        for (int i = 0; i < numCourses; i++) {
            if (indegrees[i] == 0){
                queue.add(i);
            }
        }
        while (!queue.isEmpty()){
            numCourses--;
            Integer inDegree  = queue.poll();
            for (Integer outDegree  : adjacencyies.get(inDegree)) {
                if (--indegrees[outDegree] == 0){
                    queue.add(outDegree);
                }
            }
        }
        return numCourses ==0;
    }

    //dfs
    public  boolean canFinish1(int numCourses, int[][] prerequisites) {
        visited = new int[numCourses];
        edges = new ArrayList<>();
        for (int i = 0; i < numCourses; i++) {
            edges.add(new ArrayList<Integer>());
        }
        for (int[] prerequisite : prerequisites) {
            edges.get(prerequisite[1]).add(prerequisite[0]);
        }
        for (int i = 0; i < numCourses; i++) {
            if (visited[i] == 0){
                dfs(i);
            }
        }
        return valid;
    }

    public void dfs(int u){
        visited[u] = 1;
        for (Integer edge : edges.get(u)) {
            if (visited[edge] == 0){
                dfs(edge);
                if (!valid){
                    return;
                }
            }else if (visited[edge] == 1){
                valid = false;
                return;
            }
        }
        visited[u]= 2;
    }

}
